#import "FlutterOssPlugin.h"
#if __has_include(<flutter_oss_plugin/flutter_oss_plugin-Swift.h>)
#import <flutter_oss_plugin/flutter_oss_plugin-Swift.h>
#else
// Support project import fallback if the generated compatibility header
// is not copied when this plugin is created as a library.
// https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816
#endif

#import <AliyunOSSiOS/OSSService.h>
#import "OssManager.h"

@interface FlutterOssPlugin()
@property (nonatomic, strong) FlutterMethodChannel *methodChannel;
@property (nonatomic, strong) OssManager *ossManager;

@property (nonatomic, strong) NSMutableDictionary *ossTaskDic;

@end

@implementation FlutterOssPlugin

- (NSMutableDictionary *)ossTaskDic{
    if (!_ossTaskDic) {
        _ossTaskDic = [NSMutableDictionary dictionary];
    }
    return  _ossTaskDic;
}

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    [SwiftFlutterOssPlugin registerWithRegistrar:registrar];
    
    FlutterMethodChannel *methodChannel = [FlutterMethodChannel methodChannelWithName:@"flutter_oss_plugin" binaryMessenger:[registrar messenger]];
    
    FlutterOssPlugin *ossPlugin = [FlutterOssPlugin new];
    ossPlugin.methodChannel = methodChannel;
    
    [registrar addMethodCallDelegate:ossPlugin channel:methodChannel];
}

- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {

    NSString *methodName = call.method;
    NSLog(@"方法调用%@",methodName);
    if([methodName isEqualToString:@"initOss"]){
        if(_ossManager == nil){
            _ossManager = [[OssManager alloc] init];
        }
        [_ossManager initClient:call.arguments[@"endPoint"] andStsServer:call.arguments[@"stsServer"] andNeedLog:[call.arguments[@"needLog"] boolValue] //此处强转不知道对错
                   andRetryTime: [call.arguments[@"retryNum"] intValue] andRequestTimeout:[call.arguments[@"connectOutTime"] intValue]  andSocketTimeout:[call.arguments[@"socketOutTime"] intValue]  ];
        result(@"");
    }else if([methodName isEqualToString:@"uploadFile"]){
        NSString *tag = call.arguments[@"backTag"];//监听标记用于progress/error/success反馈给flutter
        if(_ossManager == nil){
            result([FlutterError errorWithCode:@"-1" message:@"manager unInit" details:@"please call initOss before call this method"]);
            return;
        }
        
        __weak typeof(self)weakself = self;
//        NSDictionary *taskDic
//        OSSTask *ossTask
        NSDictionary *taskDic = [_ossManager uploadFileByPath:call.arguments[@"filePath"] andName:call.arguments[@"objectName"] bucketName:call.arguments[@"bucketName"] progress:^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
            NSLog(@"进度---%lld, %lld, %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);
            
            double value = (double)totalBytesSent/totalBytesExpectedToSend*100.00;
            NSLog(@"进度百分比%f",value);
            [weakself.methodChannel invokeMethod:@"progressCallBack" arguments:@{@"progress":[NSNumber numberWithDouble:value],@"tag":tag}];
        } taskBlock:^id _Nonnull(OSSTask * _Nonnull task) {

            if (!task.error) {
                
                if (![weakself.ossTaskDic objectForKey:tag]) {
                    result(@"-1");
                    return nil;
                }
                
                NSLog(@"upload object success!");
                OSSPutObjectResult *result = task.result;
                NSLog(@"上传成功 Result - requestId: %@, headerFields: %@, servercallback: %@",
                      result.requestId,
                      result.httpResponseHeaderFields,
                      result.serverReturnJsonString);
                //
                NSString *openUrlStr = [weakself.ossManager getPublicURLWithObjectName:call.arguments[@"objectName"]];
                NSLog(@"看看我的openUrl：%@",openUrlStr);
                [weakself.methodChannel invokeMethod:@"completeCallBack" arguments:@{@"requestId":openUrlStr,@"tag":tag}];

            } else {
                NSLog(@"上传失败--upload object failed, error: %@" , task.error);
                [weakself.methodChannel invokeMethod:@"clientError" arguments:@{@"errorMessage":task.error,@"tag":tag}];

            }
            result(@"");
            return nil;
        }];
        [weakself.ossTaskDic setObject:taskDic forKey:tag];//ossTask

    }else if ([methodName isEqualToString:@"cancelTask"]) {
        NSString *tag = call.arguments[@"backTag"];
//        OSSTask *task = self.ossTaskDic[tag];
        NSDictionary *dic = [self excuteCancel:tag task:self.ossTaskDic[tag]];
        NSLog(@"取消状态%@",dic);
        [self.ossTaskDic removeObjectForKey:tag];
        [self.methodChannel invokeMethod:@"cancelTask" arguments:@{@"tasks":@[dic]}];
        
    }else if ([methodName isEqualToString:@"cancelAllTask"]) {
        
        NSMutableArray *taskList = [NSMutableArray array];
        
        for (NSString *tag in self.ossTaskDic) {
            NSDictionary *resultDic = [self excuteCancel:tag task:[self.ossTaskDic objectForKey:tag]];
            [taskList addObject:resultDic];
            NSLog(@"cancelAllTask取消状态%@",resultDic);

        }

        [self.ossTaskDic removeAllObjects];
        [self.methodChannel invokeMethod:@"cancelTask" arguments:@{@"tasks":taskList}];

//        NSString *tag = call.arguments[@"backTag"];
//        OSSTask *task = self.ossTaskDic[tag];
//        NSDictionary *dic = [self excuteCancel:tag task:task];
//        NSLog(@"取消状态%@",dic);
//        [self.methodChannel invokeMethod:@"cancelTask" arguments:@{@"tasks":@[dic]}];
    }else if ([methodName isEqualToString:@"getFilePath"]){
        NSString *constrainURL = @"";
        if (_ossManager == nil) {
            result(constrainURL);
            return;
        }
        __weak typeof(self)weakself = self;

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSString *url = [weakself.ossManager getConstraiURLWithObjectName:call.arguments[@"objectName"] isSign:[call.arguments[@"isSign"] boolValue] bucketName:call.arguments[@"bucketName"]];
            dispatch_async(dispatch_get_main_queue(), ^{
                result(url);
            });
        });
    }else if ([methodName isEqualToString:@"destroyManager"]){
        _ossManager = nil;
    }
}

- (NSDictionary *)excuteCancel:(NSString *)tag task:(NSDictionary *)ossAsyncTask {//OSSTask
    int code = 0;
    NSString *msg = @"结束任务失败";
    OSSTask *task = ossAsyncTask[@"task"];
    if (task.isCompleted) {
        code = 2;
        msg = @"任务已完成无法结束";
    } else if (!task.isCancelled) {
        code = 1;
        msg = @"任务已取消";
        OSSPutObjectRequest *put = ossAsyncTask[@"put"];
        [put cancel];
        NSLog(@"看看任务取消了吗？%d",task.isCancelled);
    }
    return [NSDictionary dictionaryWithObjects:@[tag,[NSNumber numberWithInt:code], msg] forKeys:@[@"tag", @"code", @"msg"]];
}

@end
